package thread;

/**
 * Description:
 * Date: 2024-03-08
 */
public class MyBlockingQueue {   //加锁 和 wait 和 notify   还有内存可见性 的volatile
    private static String[] data = new String[100];
    private volatile static int head = 0; //volatile 是为了内存可见性
    private volatile static int end = 0;
    private volatile static int size = 0;
    public void put(String elem) throws InterruptedException {
        synchronized (this) {  //加锁是为了让别的线程阻塞
            while (size == data.length) {
                this.wait(); //队列满了就阻塞等待
            }
            data[end] = elem;
            end++;
            if (end == data.length) {
                end = 0;
            }
            size++;
            this.notify(); //唤醒put 里面的wait
        }
    }
    public String take() throws InterruptedException {
        synchronized (this) {
            while (size == 0) {
                this.wait(); //队列空就阻塞等待添加  这里是死等
            }
            String tmp = data[head];
            head++;
            if (head == data.length) {
                head = 0;
            }
            size--;
            this.notify(); //唤醒take 里面的wait
            return tmp;
        }
    }


}
 class Demo7{
     public static void main(String[] args) {
         MyBlockingQueue myBlockingQueue = new
                 MyBlockingQueue();
         Thread t1 = new Thread(()->{
             while (true) {
                 try {
                     String tmp = myBlockingQueue.take();
                     System.out.println("消耗元素" + tmp);
                 } catch (InterruptedException e) {
                     throw new RuntimeException(e);
                 }
             }
         });

         Thread t2 = new Thread(()->{
            int a = 1;
             while (true) {
                 try {
                     myBlockingQueue.put(a + "");
                     System.out.println("生产元素" + a);
                     Thread.sleep(500); //让t2 生产一个后休息0.5秒
                 } catch (InterruptedException e) {
                     throw new RuntimeException(e);
                 }
                 a++;
             }
         });
         t1.start();
         t2.start();
     }

}
